package com.ruoyi.calculationSalary.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.calculationSalary.service.CalculationSalaryService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.compensationManagement.domain.PositionSettings;
import com.ruoyi.compensationManagement.service.ICompensationSalarySettingService;
import com.ruoyi.compensationManagement.service.IPositionSettingsService;
import com.ruoyi.core.service.AttendanceCalculationService;
import com.ruoyi.out.service.IUserOvertimeLeaveService;
import com.ruoyi.out.service.impl.BaseService;
import com.ruoyi.system.domain.SysUserPositionLevel;
import com.ruoyi.system.domain.SysUserPositionLevelHistory;
import com.ruoyi.system.domain.SysUserSalaryHistory;
import com.ruoyi.system.service.ISysUserPositionLevelHistoryService;
import com.ruoyi.system.service.ISysUserSalaryHistoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 薪资计算Service业务层处理
 *
 * @author Fangz.zhu
 * @Date 2022-10-07
 * @explain
 */
@Service
public class CalculationSalaryServiceImpl implements CalculationSalaryService {
    private static final Logger logger = LoggerFactory.getLogger("calculation_salary");
    @Autowired
    private IUserOvertimeLeaveService userOvertimeLeaveService;
    @Autowired
    private AttendanceCalculationService attendanceCalculationService;
    @Autowired
    private IPositionSettingsService positionSettingsService;
    @Autowired
    private ICompensationSalarySettingService compensationSalarySettingService;
    @Autowired
    private ISysUserSalaryHistoryService sysUserSalaryHistoryService;
    @Autowired
    private ISysUserPositionLevelHistoryService sysUserPositionLevelHistoryService;

    /**
     * 哺乳假扣款 = 哺乳假扣基本工资 + 哺乳假扣基础性绩效工资 + 哺乳假扣奖励性绩效工资
     * 哺乳假扣基本工资 = 基本工资/当月满考勤数 * 0.25；
     * 哺乳假扣基础性绩效工资 = 0；
     * 哺乳假扣奖励性绩效工资 = 当月奖励性绩效工资。
     * {
     * "lessen_base_pay":"xxx",
     * "lessen_base_performance_pay":"0",
     * "lessen_incentive_performance_pay":"xxx"
     * }
     */
    @Override
    public Map<String, String> lactationLeave(Long userId, Date nowDate) {
        try {
            //每日考勤时间(8小时)
            Double attendanceTimeEveryDay = attendanceCalculationService.getAttendanceTimeEveryDay().doubleValue();
            //哺乳假期间，基本工资发放比例
            double basicSalaryRateToBreastFeeding = attendanceCalculationService.getBasicSalaryRateToBreastFeeding().doubleValue();
            //哺乳假期间，基础性绩效工资发放比例
            double basicMeritSalaryRateToBreastFeeding = attendanceCalculationService.getBasicMeritSalaryRateToBreastFeeding().doubleValue();
            //哺乳假期间，奖励性绩效发放比例
            double rewardPerformanceRateToBreastFeeding = attendanceCalculationService.getRewardPerformanceRateToBreastFeeding().doubleValue();
            //当月哺乳假小时数
            Double breastFeedingLeaveHourForMonth = attendanceCalculationService.getBreastFeedingLeaveHourForMonth(userId, DateUtils.parseDateToStr("yyyy-MM", nowDate));
            //当月满考勤数
            double attendanceDay = 21.75;
            //历史岗位等级对象
            SysUserPositionLevelHistory sysUserPositionLevelHistory = sysUserPositionLevelHistoryService.getPositionsByUserIdAndNowDate(userId, nowDate);
            //历史岗位薪级信息
            PositionSettings positionSetting = positionSettingsService.selectPositionSettingsByPositionId(sysUserPositionLevelHistory.getPositionId());
            //获取传入月份时的薪级等级
            SysUserSalaryHistory userSalaryHistory = sysUserSalaryHistoryService.getSalaryHistoryByUserIdAndNowDate(userId, nowDate);
            //基本工资(基础+薪级)
            double positionSalary = positionSetting.getPositionSalary().doubleValue() + compensationSalarySettingService.selectCompensationSalarySettingByPayId(userSalaryHistory.getPayId()).getPayWages().doubleValue();
            //当月基础性绩效工资
            double basicPerformancePay = positionSetting.getBasicPerformancePay().doubleValue();
            //当月奖励性绩效工资
            double incentivePerformancePay = positionSetting.getIncentivizedPerformancePay().doubleValue();
            Map<String, String> map = new HashMap<>();
            map.put("lessen_base_pay", String.valueOf(breastFeedingLeaveHourForMonth / attendanceTimeEveryDay * positionSalary / attendanceDay * (1 - basicSalaryRateToBreastFeeding)));
            map.put("lessen_base_performance_pay", String.valueOf(basicPerformancePay * (1 - basicMeritSalaryRateToBreastFeeding)));
            map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * (1 - rewardPerformanceRateToBreastFeeding)));
            return map;
        } catch (Exception e) {
            logger.error("CalculationSalary_lactationLeave_error,{}", JSONObject.toJSONString(e));
            return null;
        }
    }

    /**
     * 事假扣款 = 事假扣基本工资 + 事假扣基础性绩效工资 + 事假扣奖励性绩效工资
     * 年累计事假 <= 20天，扣事假基本工资 = 0；
     * 20天 < 年累计事假 <= 30天，扣事假基本工资 = 当月事假小时数/6.5 * 基本工资/当月满考勤数 * 0.2；
     * 30天 < 年累计事假 <= 50天，扣事假基本工资 = 当月事假小时数/6.5 * 基本工资/当月满考勤数 * 0.5；
     * 年累计事假 > 50天，扣事假基本工资 = 当月事假小时数/6.5 * 基本工资/当月满考勤数；
     * 扣事假基础性绩效工资 = 0；
     * 1天 < 月累计事假 <= 7天，扣事假奖励性绩效工资 = 当月事假小时数/6.5 * 奖励性绩效工资/当月满考勤数；
     * 7天 < 月累计事假 <= 10天，扣事假奖励性绩效工资 = 奖励性绩效工资 * 0.5；
     * 月累计事假 > 10天，扣事假奖励性绩效工资 = 奖励性绩效工资；
     * {
     * "lessen_base_pay":"xxx",
     * "lessen_base_performance_pay":"0",
     * "lessen_incentive_performance_pay":"xxx"
     * }
     */
    @Override
    public Map<String, String> compassionateLeave(Long userId, Date nowDate) {
        try {
            //每日考勤时间(8小时)
            Double attendanceTimeEveryDay = attendanceCalculationService.getAttendanceTimeEveryDay().doubleValue();
            //获取满考勤天数
            double attendanceDay = 21.75;
            //历史岗位等级对象
            SysUserPositionLevelHistory sysUserPositionLevelHistory = sysUserPositionLevelHistoryService.getPositionsByUserIdAndNowDate(userId, nowDate);
            //历史岗位薪级信息
            PositionSettings positionSetting = positionSettingsService.selectPositionSettingsByPositionId(sysUserPositionLevelHistory.getPositionId());
            //获取传入月份时的薪级等级
            SysUserSalaryHistory userSalaryHistory = sysUserSalaryHistoryService.getSalaryHistoryByUserIdAndNowDate(userId, nowDate);
            //传入月时的年累计事假天数
            double leaveDay = attendanceCalculationService.getPersonnelLeaveHourBeforeDate(userId, DateUtils.parseDateToStr("yyyy", nowDate)) / attendanceDay;
            //传入月时的 月累计事假小时数
            Double monthLeaveHourNum = attendanceCalculationService.getPersonnelLeaveHourForMonth(userId, DateUtils.parseDateToStr("yyyy-MM", nowDate));
            //基本工资(基础+薪级)
            double positionSalary = positionSetting.getPositionSalary().doubleValue() + compensationSalarySettingService.selectCompensationSalarySettingByPayId(userSalaryHistory.getPayId()).getPayWages().doubleValue();
            //当月奖励性绩效工资
            Double incentivePerformancePay = positionSetting.getIncentivizedPerformancePay().doubleValue();
            //传入月时的 月累计事假天数
            Double monthLeaveDay = attendanceCalculationService.getPersonnelLeaveDayForMonth(userId, DateUtils.parseDateToStr("yyyy-MM", nowDate));
            //上月年累计事假天数
            double lastYearTotalPersonalLeaveDays = leaveDay - monthLeaveDay;
            Map<String, String> map = new HashMap<>();
            if (monthLeaveDay > 0) {
                if (leaveDay <= 20) {
                    map.put("lessen_base_pay", "0");
                }
                if (leaveDay > 20 && leaveDay <= 30) {
                    if (lastYearTotalPersonalLeaveDays >= 20) {
                        //不是第一次年累计超过20天
                        map.put("lessen_base_pay", String.valueOf(monthLeaveHourNum / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.2));
                    } else {
                        //这个月第一次年累计超过20天
                        map.put("lessen_base_pay", String.valueOf((leaveDay - 20) * positionSalary / attendanceDay * 0.2));
                    }
                }
                if (leaveDay > 30 && leaveDay <= 50) {
                    if (lastYearTotalPersonalLeaveDays >= 30) {
                        //不是第一次年累计超过30天
                        map.put("lessen_base_pay", String.valueOf(monthLeaveHourNum / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.5));
                    } else {
                        //这个月第一次年累计超过30天
                        map.put("lessen_base_pay", String.valueOf(((leaveDay - 30) * positionSalary / attendanceDay * 0.5) + ((30 - lastYearTotalPersonalLeaveDays) * positionSalary / attendanceDay * 0.2)));
                    }
                }
                if (leaveDay > 50) {
                    if (lastYearTotalPersonalLeaveDays >= 50) {
                        //不是第一次年累计超过50天
                        map.put("lessen_base_pay", String.valueOf(monthLeaveHourNum / attendanceTimeEveryDay * positionSalary / attendanceDay));
                    } else {
                        //这个月第一次年累计超过50天
                        map.put("lessen_base_pay", String.valueOf(((leaveDay - 50) * positionSalary / attendanceDay) + ((50 - lastYearTotalPersonalLeaveDays) * positionSalary / attendanceDay * 0.5)));
                    }
                }
            } else {
                map.put("lessen_base_pay", "0");
            }

            map.put("lessen_base_performance_pay", "0");
            if (monthLeaveDay == 0)
                map.put("lessen_incentive_performance_pay", "0.0");
            if (monthLeaveDay > 1 && monthLeaveDay <= 7)
                map.put("lessen_incentive_performance_pay", String.valueOf(monthLeaveHourNum / 6.5 * incentivePerformancePay / attendanceDay));
            if (monthLeaveDay > 7 && monthLeaveDay <= 10)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.5));
            if (monthLeaveDay > 10)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay));
            return map;
        } catch (Exception e) {
            logger.error("CalculationSalary_compassionateLeave_error,{}", JSONObject.toJSONString(e));
            return null;
        }
    }

    /**
     * 病假扣款 = 病假扣基本工资 + 病假扣基础性绩效工资 + 病假扣奖励性绩效工资
     * 年累计病假 <= 2个月（60天=60*6.5=390小时），扣基本工资 = 0；
     * 2个月 < 年累计病假 <= 6个月（180天=1170小时），且 工作年限（入职时间） < 10 年，扣基本工资 = 全年超出2个月的当月病假小时数/6.5 * 基本工资(岗位工资+薪级工资)/当月满考勤天数 * 0.1；
     * 2个月 < 年累计病假 <= 6个月（180天=1170小时），且 工作年限（入职时间） >= 10 年，扣基本工资 = 0；
     * 年累计病假 > 6个月，且 工作年限（入职时间） < 10 年，扣基本工资 = 全年超出6个月的当月病假小时数/6.5 * 基本工资(岗位工资+薪级工资)/当月满考勤天数 * 0.3；
     * 年累计病假 > 6个月，且10年 <= 工作年限（入职时间） < 20 年，扣基本工资 = 全年超出6个月的当月病假小时数/6.5 * 基本工资(岗位工资+薪级工资)/当月满考勤天数 * 0.2；
     * 年累计病假 > 6个月，且 工作年限（入职时间） >= 20 年，扣基本工资 = 全年超出6个月的当月病假小时数/6.5 * 基本工资(岗位工资+薪级工资)/当月满考勤天数 * 0.1；
     * 特殊荣誉（工资编辑页面手工设置），扣基本工资 = 0
     * 扣基础性绩效工资 = 0
     * 月累计病假 < 1 天，扣奖励性绩效工资 = 0
     * 1天 <= 月累计病假 < 5天（5*6.5=32.5小时），且 工作年限（入职时间）< 10年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.15；
     * 1天 <= 月累计病假 < 5天（5*6.5=32.5小时），且10年 <= 工作年限（入职时间）< 20年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.1；
     * 1天 <= 月累计病假 < 5天（5*6.5=32.5小时），且 工作年限（入职时间） >= 20年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.05；
     * 5天 <= 月累计病假 < 10天（10*6.5=65小时），且 工作年限（入职时间）< 10年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.2；
     * 5天 <= 月累计病假 < 10天（10*6.5=65小时），且 10年 <= 工作年限（入职时间）< 20年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.15；
     * 5天 <= 月累计病假 < 10天（10*6.5=65小时），且 工作年限（入职时间） >= 20年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.1；
     * 10天 <= 月累计病假 < 15天（15*6.5=97.5小时），且 工作年限（入职时间）< 10年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.25；
     * 10天 <= 月累计病假 < 15天（15*6.5=97.5小时），且 10年 <= 工作年限（入职时间）< 20年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.2；
     * 10天 <= 月累计病假 < 15天（15*6.5=97.5小时），且 工作年限（入职时间） >= 20年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.15；
     * 15天 <= 月累计病假，且 工作年限（入职时间）< 10年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.3；
     * 15天 <= 月累计病假，且 10年 <= 工作年限（入职时间）< 20年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.25；
     * 15天 <= 月累计病假，且 工作年限（入职时间） >= 20年，扣奖励性绩效工资 = 当月奖励性绩效工资 * 0.2；
     * 年累计病假 > 6个月（180*6.5=1170小时），扣奖励性绩效工资 = 当月奖励性绩效工资；
     * {
     * "lessen_base_pay":"xxx",
     * "lessen_base_performance_pay":"0",
     * "lessen_incentive_performance_pay":"xxx"
     * }
     */
    @Override
    public Map<String, String> sickLeave(Long userId, Date nowDate) {
        try {
            //每日考勤时间（8小时）
            Double attendanceTimeEveryDay = attendanceCalculationService.getAttendanceTimeEveryDay().doubleValue();
            //获取满考勤天数
            double attendanceDay = 21.75;
            //历史岗位等级对象
            SysUserPositionLevelHistory sysUserPositionLevelHistory = sysUserPositionLevelHistoryService.getPositionsByUserIdAndNowDate(userId, nowDate);
            //历史岗位薪级信息
            PositionSettings positionSetting = positionSettingsService.selectPositionSettingsByPositionId(sysUserPositionLevelHistory.getPositionId());
            //获取传入月份时的薪级等级
            SysUserSalaryHistory userSalaryHistory = sysUserSalaryHistoryService.getSalaryHistoryByUserIdAndNowDate(userId, nowDate);
            //基本工资(基础+薪级)
            double positionSalary = positionSetting.getPositionSalary().doubleValue() + compensationSalarySettingService.selectCompensationSalarySettingByPayId(userSalaryHistory.getPayId()).getPayWages().doubleValue();
            //当月奖励性绩效工资
            Double incentivePerformancePay = positionSetting.getIncentivizedPerformancePay().doubleValue();
            //传入月时 年累计病假小时数
            Double sickLeaveHourForYear = attendanceCalculationService.getSickLeaveHourBeforeDate(userId, DateUtils.parseDateToStr("yyyy-MM", nowDate));
            //传入月时 月累计病假小时数
            Double sickLeaveHourForMonth = attendanceCalculationService.getSickLeaveHourForMonth(userId, DateUtils.parseDateToStr("yyyy-MM", nowDate));
            //传入月时 的上一个月的年累计病假数
            Double sickLeaveHourForYearOfLastMonth = sickLeaveHourForYear - sickLeaveHourForMonth;
            //入职年限
            BigDecimal employeeAge = attendanceCalculationService.getEmployeeAge(userId);
            Map<String, String> map = new HashMap<>();
            // TODO 特殊荣誉未实现
            if (sickLeaveHourForMonth > 0) {
                //全年病假时长<=2个月
                if (sickLeaveHourForYear <= 60 * attendanceTimeEveryDay) {
                    map.put("lessen_base_pay", "0");
                }
                //2个月<全年病假时长<6个月
                if (sickLeaveHourForYear > 60 * attendanceTimeEveryDay && sickLeaveHourForYear <= 180 * attendanceTimeEveryDay && employeeAge.doubleValue() < 10) {
                    if (sickLeaveHourForYearOfLastMonth >= 60 * attendanceTimeEveryDay) {
                        //不是第一次年累计病假大于2个月
                        map.put("lessen_base_pay", String.valueOf(sickLeaveHourForMonth / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.1));
                    } else {
                        //第一次传入月时 的年累计病假大于2个月
                        map.put("lessen_base_pay", String.valueOf((sickLeaveHourForYear - 60 * attendanceTimeEveryDay) / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.1));
                    }
                }
                if (sickLeaveHourForYear > 60 * attendanceTimeEveryDay && sickLeaveHourForYear <= 180 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 10) {
                    map.put("lessen_base_pay", "0");
                }
                //全年病假时长>6个月
                if (sickLeaveHourForYear > 180 * attendanceTimeEveryDay && employeeAge.doubleValue() < 10) {
                    if (sickLeaveHourForYearOfLastMonth >= 180 * attendanceTimeEveryDay) {
                        //不是第一次年累计病假大于6个月
                        map.put("lessen_base_pay", String.valueOf(sickLeaveHourForMonth / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.3));
                    } else {
                        //传入月时 第一次年累计病假大于6个月
                        map.put("lessen_base_pay", String.valueOf(((sickLeaveHourForYear - 180 * attendanceTimeEveryDay) / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.3))
                                + ((180 * attendanceTimeEveryDay - sickLeaveHourForYearOfLastMonth)) / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.1);
                    }
                }
                if (sickLeaveHourForYear > 180 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 10 && employeeAge.doubleValue() < 20) {
                    if (sickLeaveHourForYearOfLastMonth >= 180 * attendanceTimeEveryDay) {
                        //不是第一次年累计病假大于6个月
                        map.put("lessen_base_pay", String.valueOf(sickLeaveHourForMonth / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.2));
                    } else {
                        //传入月时 第一次年累计病假大于6个月
                        map.put("lessen_base_pay", String.valueOf((sickLeaveHourForYear - 180 * attendanceTimeEveryDay) / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.2));
                    }
                }
                if (sickLeaveHourForYear > 180 * attendanceTimeEveryDay && employeeAge.doubleValue() > 20) {
                    if (sickLeaveHourForYearOfLastMonth >= 180 * attendanceTimeEveryDay) {
                        //不是第一次年累计病假大于6个月
                        map.put("lessen_base_pay", String.valueOf(sickLeaveHourForMonth / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.1));
                    } else {
                        //传入月时 第一次年累计病假大于6个月
                        map.put("lessen_base_pay", String.valueOf((sickLeaveHourForYear - 180 * attendanceTimeEveryDay) / attendanceTimeEveryDay * positionSalary / attendanceDay * 0.1));
                    }
                }
            } else {
                map.put("lessen_base_pay", "0");
            }

            map.put("lessen_base_performance_pay", "0");
            if (sickLeaveHourForMonth < 1 * attendanceTimeEveryDay)
                map.put("lessen_incentive_performance_pay", "0");
            if (sickLeaveHourForMonth >= 1 * attendanceTimeEveryDay && sickLeaveHourForMonth < 5 * attendanceTimeEveryDay && employeeAge.doubleValue() < 10)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.15));
            if (sickLeaveHourForMonth >= 1 * attendanceTimeEveryDay && sickLeaveHourForMonth < 5 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 10 && employeeAge.doubleValue() < 20)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.1));
            if (sickLeaveHourForMonth >= 1 * attendanceTimeEveryDay && sickLeaveHourForMonth < 5 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 20)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.05));

            if (sickLeaveHourForMonth >= 5 * attendanceTimeEveryDay && sickLeaveHourForMonth < 10 * attendanceTimeEveryDay && employeeAge.doubleValue() < 10)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.2));
            if (sickLeaveHourForMonth >= 5 * attendanceTimeEveryDay && sickLeaveHourForMonth < 10 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 10 && employeeAge.doubleValue() < 20)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.15));
            if (sickLeaveHourForMonth >= 5 * attendanceTimeEveryDay && sickLeaveHourForMonth < 10 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 20)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.1));

            if (sickLeaveHourForMonth >= 10 * attendanceTimeEveryDay && sickLeaveHourForMonth < 15 * attendanceTimeEveryDay && employeeAge.doubleValue() < 10)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.25));
            if (sickLeaveHourForMonth >= 10 * attendanceTimeEveryDay && sickLeaveHourForMonth < 15 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 10 && employeeAge.doubleValue() < 20)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.2));
            if (sickLeaveHourForMonth >= 10 * attendanceTimeEveryDay && sickLeaveHourForMonth < 15 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 20)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.15));

            if (sickLeaveHourForMonth >= 15 * attendanceTimeEveryDay && employeeAge.doubleValue() < 10)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.3));
            if (sickLeaveHourForMonth >= 15 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 10 && employeeAge.doubleValue() < 20)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.25));
            if (sickLeaveHourForMonth >= 15 * attendanceTimeEveryDay && employeeAge.doubleValue() >= 20)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay * 0.2));

            if (sickLeaveHourForYear > 180 * attendanceTimeEveryDay)
                map.put("lessen_incentive_performance_pay", String.valueOf(incentivePerformancePay));

            return map;
        } catch (Exception e) {
            logger.error("CalculationSalary_sickLeave_error,{}", JSONObject.toJSONString(e));
            return null;
        }
    }

    /**
     * 加班工资=加班基本工资+加班基础性绩效工资+加班奖励性绩效工资
     * 加班基本工资=法定工作日加班基本工资+休息日加班基本工资+法定休假日加班基本工资
     * =法定工作日加班(h)/6.5 * 基本工资(岗位工资+薪级工资)/当月满考勤天数 * 1.5 + 休息日加班(h)/6.5 * 基本工资(岗位工资+薪级工资)/当月满考勤天数 * 2 + 法定休假日加班(h)/6.5 * 基本工资(岗位工资+薪级工资)/当月满考勤天数 * 3
     * 加班基础性绩效工资=法定工作日加班基础性绩效工资+休息日加班基础性绩效工资+法定休假日加班基础性绩效工资
     * =法定工作日加班(h)/6.5 * 基础性绩效工资/当月满考勤天数 * 1.5 + 休息日加班(h)/6.5 * 基础性绩效工资/当月满考勤天数 * 2 + 法定休假日加班(h)/6.5 * 基础性绩效工资/当月满考勤天数 * 3
     * 加班奖励性绩效工资=法定工作日加班奖励性绩效工资+休息日加班奖励性绩效工资+法定休假日加班奖励性绩效工资
     * =法定工作日加班(h)/6.5 * 奖励性绩效工资/当月满考勤天数 * 1.5 + 休息日加班(h)/6.5 * 奖励性绩效工资/当月满考勤天数 * 2 + 法定休假日加班(h)/6.5 * 奖励性绩效工资/当月满考勤天数 * 3
     * {
     * "workOvertime_base_pay":"xxx",
     * "workOvertime_base_performance_pay":"xxx",
     * "workOvertime_incentive_performance_pay":"xxx"
     * }
     */
    @Override
    public Map<String, String> workOvertime(Long userId, Date nowDate) {
        try {
            //每日考勤时间（8小时）
            Double attendanceTimeEveryDay = attendanceCalculationService.getAttendanceTimeEveryDay().doubleValue();
            //获取满考勤天数
            double attendanceDay = 21.75;
            //历史岗位等级对象
            SysUserPositionLevelHistory sysUserPositionLevelHistory = sysUserPositionLevelHistoryService.getPositionsByUserIdAndNowDate(userId, nowDate);
            //历史岗位薪级信息
            PositionSettings positionSetting = positionSettingsService.selectPositionSettingsByPositionId(sysUserPositionLevelHistory.getPositionId());
            //获取传入月份时的薪级等级
            SysUserSalaryHistory userSalaryHistory = sysUserSalaryHistoryService.getSalaryHistoryByUserIdAndNowDate(userId, nowDate);
            //基本工资(基础+薪级)
            double positionSalary = positionSetting.getPositionSalary().doubleValue() + compensationSalarySettingService.selectCompensationSalarySettingByPayId(userSalaryHistory.getPayId()).getPayWages().doubleValue();
            //基础性绩效工资
            double basicPerformancePay = positionSetting.getBasicPerformancePay().doubleValue();
            //当月奖励性绩效工资
            double incentivePerformancePay = positionSetting.getIncentivizedPerformancePay().doubleValue();
            //当月法定休假日加班小时数
            Double officialHolidayDayOvertimeHour = attendanceCalculationService.getOfficialHolidayDayOvertimeHour(userId, DateUtils.parseDateToStr("yyyy-MM", nowDate));
            //当月休息日加班小时数
            Double restDayOvertimeHour = attendanceCalculationService.getRestDayOvertimeHour(userId, DateUtils.parseDateToStr("yyyy-MM", nowDate));
            //法定工作日加班小时数
            Double legalWorkingDayOvertimeHour = attendanceCalculationService.getLegalWorkingDayOvertimeHour(userId, DateUtils.parseDateToStr("yyyy-MM", nowDate));
            Map<String, String> map = new HashMap<>();
            Double workOvertime_base_pay = legalWorkingDayOvertimeHour / attendanceTimeEveryDay * positionSalary / attendanceDay * 1.5 + restDayOvertimeHour / attendanceTimeEveryDay * positionSalary / attendanceDay * 2 + officialHolidayDayOvertimeHour / attendanceTimeEveryDay * positionSalary / attendanceDay * 3;
            map.put("workOvertime_base_pay", String.valueOf(workOvertime_base_pay));
            Double workOvertime_base_performance_pay = legalWorkingDayOvertimeHour / attendanceTimeEveryDay* basicPerformancePay / attendanceDay * 1.5 + restDayOvertimeHour /attendanceTimeEveryDay * basicPerformancePay / attendanceDay * 2 + officialHolidayDayOvertimeHour / attendanceTimeEveryDay * basicPerformancePay / attendanceDay * 3;
            map.put("workOvertime_base_performance_pay", String.valueOf(workOvertime_base_performance_pay));
            Double workOvertime_incentive_performance_pay = legalWorkingDayOvertimeHour / attendanceTimeEveryDay * incentivePerformancePay / attendanceDay * 1.5 + restDayOvertimeHour / attendanceTimeEveryDay * incentivePerformancePay / attendanceDay * 2 + officialHolidayDayOvertimeHour / attendanceTimeEveryDay * incentivePerformancePay / attendanceDay * 3;
            map.put("workOvertime_incentive_performance_pay", String.valueOf(workOvertime_incentive_performance_pay));

            return map;
        } catch (Exception e) {
            logger.error("CalculationSalary_workOvertime_error,{}", JSONObject.toJSONString(e));
            return null;
        }
    }


}
